package com.paginasenlanube.service;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.imageio.ImageIO;

import org.imgscalr.Scalr;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.paginasenlanube.dao.GenericDao;
import com.paginasenlanube.model.Archive;
import com.paginasenlanube.model.DataType;
import com.paginasenlanube.model.Design;
import com.paginasenlanube.model.Image;
import com.paginasenlanube.model.ImageGallery;
import com.paginasenlanube.model.Website;
import com.paginasenlanube.utils.UserException;
import com.paginasenlanube.utils.Utils;

@Service
public class ImageServiceImpl implements ImageService {
	
	

	 @Autowired
	 @Qualifier("hibernateDao")
	 private GenericDao dao;
	  
	 public GenericDao getDao() {
		return dao;
	 }
	 
	 @Resource(name = "myProps")
	 private Properties myProps;
	 
	 @Autowired
	 private Website website;
	 
	 @Autowired
	 PagesConfigService pageService;
	
	
	public PagesConfigService getPageService() {
		return pageService;
	}
	 
	@Override
	@Transactional
	public Image saveTmpImage(MultipartFile mpf,int minWidth) throws IOException,UserException {
			  
              String imagesPath = myProps.getProperty("imagesPath");
              long websiteId = website.getId();
              if (mpf.getSize() > 0) { // writing file to a directory
            	File webDir = new File(imagesPath+"/"+websiteId);
            	webDir.mkdir();
              	File upLoadedfile = new File(imagesPath+"/"+websiteId+"/tmp_"+mpf.getOriginalFilename());
              	
              	upLoadedfile.createNewFile();
              	FileOutputStream fos = new FileOutputStream(upLoadedfile);
              	fos.write(mpf.getBytes());
              	fos.close(); //setting the value of fileUploaded variable
              }
              Image image = new Image();
              image.setFileName("tmp_"+mpf.getOriginalFilename());
              image.setFileSize(mpf.getSize()/1024+" Kb");
              image.setFileType(mpf.getContentType());  
              BufferedImage img = ImageIO.read(mpf.getInputStream());
              int width = img.getWidth();
              int height = img.getHeight();
              if(width < minWidth){
            	  image = null;
            	  throw new UserException("Image Size Error");
            	
              }
              image.setWidth(width);
              image.setHeight(height);
              
              return image;
		
	}
	
	@Override
	@Transactional
	public String saveImage(JsonArray json,Image image,int width, int height,String key){
		String jsonResponse = "{\"error\":\"null data\"}";
        String imagePath = myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+image.getFileName();
        String newFileName = Utils.getImagePrefix()+image.getFileName().substring(4);
        String newImagePath = myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+newFileName;       
        image.setFileName(newFileName);
        		
		BufferedImage out = saveImageCrop(json,imagePath);
					  out = paintComponent(out,width,height);
		try {
			ImageIO.write(out, image.getFileType().substring(6), new File(newImagePath));
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		if(key.equals("design")){
			
		
		if(website.getDesign().getImage()!= null){
			File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+website.getDesign().getImage().getFileName());
			f_old.delete();
			}
      	website.getDesign().setImage(image); 
        website.getDesign().setBgThemeType(Design.BgTheme.UPLOAD_IMAGE);
        dao.update(website.getDesign());
        jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"caption\":\""+image.getCaption()+"\",\"url\":\""+image.getUrl()+"\",\"key\":\""+key+"\"}";
		}else if(key.equals("header")){
			
			if(website.getHeader().getLogo()!= null){
				File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+website.getHeader().getLogo().getFileName());
				f_old.delete();
				}
	      	website.getHeader().setLogo(image); 
	      	dao.update(website.getHeader());
	      	jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"caption\":\""+image.getCaption()+"\",\"url\":\""+image.getUrl()+"\",\"key\":\""+key+"\"}";	
		}else if (key.equals("header_gal")){
			 String title = Utils.getJsonVar(json,"title");
			 String caption = Utils.getJsonVar(json,"caption");
			 String url = Utils.getJsonVar(json,"url");
			 int lastPosition = dao.getObjectValueByMaxCriteria(Image.class,"position",null);
			 image.setTitle(title);
			 image.setCaption(caption);
			 image.setPosition(lastPosition+1);
			 if(!url.isEmpty())
			 image.setUrl(url);
			 image.setHeader_id(website.getHeader().getId());
			 dao.add(image);
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"caption\":\""+image.getCaption()+"\",\"url\":\""+image.getUrl()+"\",\"key\":\""+key+"\"}"; 
		}else if (key.equals("dataType")){
			 dao.add(image);
			 Long id = (long) 0;
			 try{
				 id = Long.parseLong(Utils.getJsonVar(json,"itemID"));
				 DataType dt = dao.getObjectById(DataType.class, id);
				 Image old_image = dt.getImage();
				 if(old_image != null){
					 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+old_image.getFileName());
					 f_old.delete();
				 }
				 dt.setImage(image);
			 }catch(NumberFormatException nfe){
					
			 }
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"caption\":\""+image.getCaption()+"\",\"url\":\""+image.getUrl()+"\",\"key\":\""+key+"\"}";
				
		}else if (key.equals("archive")){
			 dao.add(image);
			 String idArchive = Utils.getJsonVar(json,"id");
			 String title = Utils.getJsonVar(json,"title");
			 String text = Utils.getJsonVar(json,"text");
			 String tags = Utils.getJsonVar(json,"tags");
			 String url = Utils.getJsonVar(json,"video_url");
			 Long archive_id = (long) 0;
			 Long page_id = (long) 0;
			 try{
				 page_id = Long.parseLong(Utils.getJsonVar(json,"pageId"));
				 archive_id = Long.parseLong(idArchive);
			 }catch(NumberFormatException nfe){
					
			 }
			 if(archive_id>0){//edit archive image
			 Archive archive = dao.getObjectById(Archive.class, archive_id);
			 Image old_image = archive.getImage();
			 if(old_image != null){
				 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+old_image.getFileName());
				 f_old.delete();
			 }
			 archive.setTitle(title);
			 archive.setText(text);
			 archive.setTags(tags);
			 archive.setVideo_url(url);
			 archive.setImage(image);
			 dao.update(archive);
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+archive.getId()+"\",\"title\":\""+archive.getTitle()+"\",\"key\":\""+key+"\"}";
			 }else{//add new archive
			 Map<String, Object> params = new HashMap<String, Object>();
			 params.put("pageId", page_id);
			 int lastPosition = 0;
			 try{
			  lastPosition = dao.getObjectValueByMaxCriteria(Archive.class,"position",params);
			 }catch(Exception e){
				 
			 }
			 Archive ar = new Archive();
			 ar.setTitle(title);
			 ar.setText(text);
			 ar.setTags(tags);
			 ar.setVideo_url(url);
			 ar.setPosition(lastPosition+1);
			 ar.setImage(image);
			 ar.setPageId(page_id);
			 dao.add(ar);
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+ar.getId()+"\",\"title\":\""+ar.getTitle()+"\",\"key\":\""+key+"\",\"newArchive\":\"true\"}";
			 }
			 
		}
        return jsonResponse;
	}
	
	@Override
	@Transactional
	public String saveGalleryImage(JsonArray json,Image image,int width, int height,String flag){
		String jsonResponse = "{\"error\":\"null data\"}";
		 String id = Utils.getJsonVar(json,"id");
		 String title = Utils.getJsonVar(json,"title");
		 String caption = Utils.getJsonVar(json,"caption");
		 String tags = Utils.getJsonVar(json,"tags");
		 String galId = Utils.getJsonVar(json,"galId");
		 
		  String imagePath = myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+image.getFileName();
	      String newFileName = Utils.getImagePrefix()+image.getFileName().substring(4);
	      String newImagePath = myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+newFileName;       
	      image.setFileName(newFileName);
		 
		  BufferedImage out = saveImageCrop(json,imagePath);
		  out = paintComponent(out,width,height);
		  try {
			  ImageIO.write(out, image.getFileType().substring(6), new File(newImagePath));
		  } catch (IOException e) {
			  // TODO Auto-generated catch block
			  e.printStackTrace();
		  }

		 image.setTitle(title);
		 image.setCaption(caption);
		 image.setTags(tags);
		
		 Long image_id = (long) 0;
		 Long page_id = (long) 0;
		 Long gallery_id = (long) 0;
		 try{
			 page_id = Long.parseLong(Utils.getJsonVar(json,"pageId"));
			 image_id = Long.parseLong(id);
			 gallery_id = Long.parseLong(galId);
		 }catch(NumberFormatException nfe){
				
		 }
		 if(image_id>0){//edit gallery image
			 Image old_image = dao.getObjectById(Image.class, image_id);
			 if(old_image != null){
				 File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+old_image.getFileName());
				 f_old.delete();
			 }
			 dao.update(image);
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"key\":\"gallery\"}";
			 
			 }else{//add new image
				 
			 Map<String, Object> params = new HashMap<String, Object>();
			 params.put("imageGallery_id", gallery_id);
			 int lastPosition = 0;
			 try{
			  lastPosition = dao.getObjectValueByMaxCriteria(Image.class,"position",params);
			 }catch(Exception e){
				
			 }
			 image.setPosition(lastPosition+1);
			 image.setImageGallery_id(gallery_id);
		
			 dao.add(image);
			 jsonResponse = "{\"image\":\""+website.getId()+"/"+image.getFileName()+"\",\"id\":\""+image.getId()+"\",\"title\":\""+image.getTitle()+"\",\"key\":\"gallery\",\"newImage\":\"true\"}";
			 }
		return jsonResponse;
	}
	
	



	public BufferedImage saveImageCrop(JsonArray json,String imagePath) {
					
		int x=0,y=0,x2=0,y2=0;
	
		try{
		 x = Integer.parseInt(json.get(0).getAsJsonObject().get("cropx1").getAsString());
		 y = Integer.parseInt(json.get(0).getAsJsonObject().get("cropy1").getAsString());
		 x2 = Integer.parseInt(json.get(0).getAsJsonObject().get("cropx2").getAsString());
		 y2 = Integer.parseInt(json.get(0).getAsJsonObject().get("cropy2").getAsString());
		
		}catch(NumberFormatException nfe){
			nfe.printStackTrace();
		}
		
		BufferedImage BfImage;
		BufferedImage out = null;
		try {
			File ftmp = new File(imagePath); 
			BfImage = ImageIO.read(ftmp);
			out = BfImage.getSubimage(x,y,x2-x,y2-y);
			ftmp.delete();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return out;
	}
	
	 public BufferedImage paintComponent(BufferedImage img,int width,int height) {
		 img = Scalr.resize(img, width);
	        return img;
	    }
	 
		@Override
		@Transactional
		public String daleteGalleryImage(String id) {
			long imageID = Long.parseLong(id);
			Image img = dao.getObjectById(Image.class,imageID);
			File f_old = new File(myProps.getProperty("imagesPath")+"/"+website.getId()+"/"+img.getFileName());
			f_old.delete();
			dao.delete(img);
			return "success";
		}
	 
		@Override
		@Transactional
		public Image updateImage(JsonArray json) {
			 String title = json.get(0).getAsJsonObject().get("title").getAsString();
			 String caption = json.get(0).getAsJsonObject().get("caption").getAsString();
			 String url = json.get(0).getAsJsonObject().get("url").getAsString();
			 String id = json.get(0).getAsJsonObject().get("id").getAsString();
			 long imageID = Long.parseLong(id);
			 Image image = dao.getObjectById(Image.class,imageID);
			 if(image !=null){
			 image.setTitle(title);
			 image.setCaption(caption);
			 if(!url.isEmpty())
			 image.setUrl(url);
			 dao.update(image);
			 }
			 return image;
		}
	 
	 @Override
		@Transactional
		public void updateImagePosition(JsonArray json) {
			long id1 = Long.parseLong(json.get(0).getAsJsonObject().get("id1").getAsString().substring(4));
			int pos1 = Integer.parseInt(json.get(0).getAsJsonObject().get("pos1").getAsString());
			long id2 = Long.parseLong(json.get(0).getAsJsonObject().get("id2").getAsString().substring(4));
			int pos2 = Integer.parseInt(json.get(0).getAsJsonObject().get("pos2").getAsString());
			
			Image image1 = dao.getObjectById(Image.class,id1);
			image1.setPosition(pos1);
			dao.update(image1);
			
			Image image2 = dao.getObjectById(Image.class,id2);
			image2.setPosition(pos2);
			dao.update(image2);
			
		}

}
